package com.xique.park.service.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xique.common.core.text.Convert;
import com.xique.common.core.utils.DateUtils;
import com.xique.common.core.utils.SecurityUtils;
import com.xique.common.core.utils.StringUtils;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.park.bean.domain.ParkCar;
import com.xique.park.bean.domain.ParkCarMngtype;
import com.xique.park.bean.domain.ParkGarage;
import com.xique.park.bean.domain.ParkUpdateCarLog;
import com.xique.park.bean.request.app.ParkCarAddRequest;
import com.xique.park.bean.request.app.ParkCarDeleteRequest;
import com.xique.park.bean.request.app.ParkCarEditRequest;
import com.xique.park.bean.request.web.car.ParkVisitorCarAddRequest;
import com.xique.park.bean.request.web.car.UpdateLogRequest;
import com.xique.park.bean.request.web.parkcar.BlackCarRequest;
import com.xique.park.bean.vo.web.car.ParkCarAddGarageSpaceVo;
import com.xique.park.constant.UpdateTypeConstant;
import com.xique.park.mapper.ParkCarMngtypeMapper;
import com.xique.park.mapper.ParkUpdateCarLogMapper;
import com.xique.park.service.service.IParkCarService;
import com.xique.park.service.service.IParkGarageService;
import com.xique.park.service.service.ParkUpdateCarLogService;
import com.xique.system.api.RemoteSystemUserService;
import com.xique.system.api.dto.OperateDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 记录变更 version 1.0
 */
@Service
public class ParkUpdateCarLogServiceImpl extends ServiceImpl<ParkUpdateCarLogMapper, ParkUpdateCarLog>
        implements ParkUpdateCarLogService {


    @Autowired
    private ParkUpdateCarLogMapper parkUpdateCarLogMapper;


    @Autowired
    private IParkGarageService parkGarageService;

    @Autowired
    private ParkCarMngtypeMapper parkCarMngtypeMapper;

    @Autowired
    private RemoteSystemUserService systemUserService;

    @Autowired
    private IParkCarService iParkCarService;

    @Autowired
    private IParkGarageService iParkGarageService;

    @Override
    public void generateAddParkLog(ParkCarAddRequest request, ParkCar parkCar) {
        ParkUpdateCarLog parkUpdateCarLog = new ParkUpdateCarLog();
        fieldTransConvert(request, parkUpdateCarLog);
        parkUpdateCarLog.setMngType(String.valueOf(request.getMngTypeId()));
        parkUpdateCarLog.setCarId(parkCar.getId());
        parkUpdateCarLog.setUpdateType(UpdateTypeConstant.PARK_UPDATE_ADD);
        parkUpdateCarLogMapper.insert(parkUpdateCarLog);
    }

    @Override
    public void generateDelLog(ParkCarDeleteRequest request, ParkCar parkCar) {
        ParkUpdateCarLog parkUpdateCarLog = new ParkUpdateCarLog();
        parkUpdateCarLog.setOperId(request.getUserId());
        parkUpdateCarLog.setCarId(request.getCarId());
        parkUpdateCarLog.setParkId(SecurityUtils.getParkId());
        parkUpdateCarLog.setPlates(parkCar.getPlate());
        parkUpdateCarLog.setOperName(SecurityUtils.getUsername());
        parkUpdateCarLog.setUpdateTime(new Date());
        parkUpdateCarLog.setUpdateType(UpdateTypeConstant.PARK_UPDATE_DELETE);
        parkUpdateCarLogMapper.insert(parkUpdateCarLog);
    }


    @Override
    public void generateBatchDelLog(List<ParkCar> parkCars) {
        List<ParkUpdateCarLog> parkUpdateCarLogs = new ArrayList<>();

        for (ParkCar parkCar : parkCars) {
            ParkUpdateCarLog parkUpdateCarLog = new ParkUpdateCarLog();
            parkUpdateCarLog.setPlates(parkCar.getBindPlates());
            parkUpdateCarLog.setUpdateTime(new Date());
            parkUpdateCarLog.setOperName(SecurityUtils.getUsername());
            parkUpdateCarLog.setOperId(SecurityUtils.getUserId());
            parkUpdateCarLog.setUpdateType(UpdateTypeConstant.PARK_UPDATE_DELETE);
            parkUpdateCarLog.setParkId(SecurityUtils.getParkId());
            parkUpdateCarLogs.add(parkUpdateCarLog);
        }
        this.saveBatch(parkUpdateCarLogs);
    }

    @Override
    public void generateUpdateLog(ParkCarEditRequest request, ParkCar originalCar, Integer spaces, Long mngTypeId) {
        ParkUpdateCarLog parkUpdateCarLog = new ParkUpdateCarLog();
        parkUpdateCarLog.setOperId(SecurityUtils.getUserId());
        parkUpdateCarLog.setParkId(SecurityUtils.getParkId());
        parkUpdateCarLog.setOperName(SecurityUtils.getUsername());
        parkUpdateCarLog.setSpaceList(JSONObject.toJSONString(request.getSpaceList()));
        parkUpdateCarLog.setBeginDate(request.getBeginDate());
        parkUpdateCarLog.setEndDate(request.getEndDate());
        parkUpdateCarLog.setPlates(request.getPlates());
        parkUpdateCarLog.setCarId(request.getCarId());
        parkUpdateCarLog.setUpdateTime(new Date());
        parkUpdateCarLog.setUserName(request.getUserName());
        parkUpdateCarLog.setAddress(request.getAddress());
        String updateType = UpdateTypeConstant.Park_UPDATE_DEFAULT;
        if (request.getMngTypeId() != null && !mngTypeId.equals(request.getMngTypeId())) {
            parkUpdateCarLog.setMngType(String.valueOf(request.getMngTypeId()));
            parkUpdateCarLog.setBeforeMngType(String.valueOf(mngTypeId));
            updateType = updateType + "," + UpdateTypeConstant.PARK_UPDATE_MNGTYPE;
        }

        if (request.getSpaceCnt() != null && spaces != originalCar.getSpaces()) {
            parkUpdateCarLog.setSpaceCnt(String.valueOf(request.getSpaceCnt()));
            parkUpdateCarLog.setBeforeSpaceCnt(String.valueOf(spaces));
            updateType = updateType + "," + UpdateTypeConstant.Park_UPDATE_CARNUMS;
        }

        parkUpdateCarLog.setUpdateType(updateType);
        parkUpdateCarLogMapper.insert(parkUpdateCarLog);

    }

    /**
     * 字段类型转换器
     *
     * @param request
     * @param parkUpdateCarLog
     */
    private ParkUpdateCarLog fieldTransConvert(ParkCarAddRequest request, ParkUpdateCarLog parkUpdateCarLog) {
        parkUpdateCarLog.setParkId(request.getParkId());
        parkUpdateCarLog.setUpdateTime(new Date());
        parkUpdateCarLog.setOperId(SecurityUtils.getUserId());
        parkUpdateCarLog.setOperName(SecurityUtils.getUsername());
        parkUpdateCarLog.setAddress(request.getAddress());
        parkUpdateCarLog.setPhone(request.getPhone());
        parkUpdateCarLog.setUserName(request.getUserName());
        parkUpdateCarLog.setBeginDate(request.getBeginDate());
        parkUpdateCarLog.setEndDate(request.getEndDate());
        parkUpdateCarLog.setIsGarageSpace(request.getIsGarageSpace());
        parkUpdateCarLog.setStatus(request.getStatus());
        parkUpdateCarLog.setPlates(request.getPlates());
        parkUpdateCarLog.setSpaceList(JSONObject.toJSONString(request.getSpaceList()));
        parkUpdateCarLog.setRemark(request.getRemark());
        parkUpdateCarLog.setMngType(request.getMngType());
        parkUpdateCarLog.setMayFee(request.getMayFee() != null ? request.getMayFee() : 0);
        parkUpdateCarLog.setActualFee(request.getActualFee() != null ? request.getActualFee() : 0);
        parkUpdateCarLog.setPayType(request.getPayType() != null ? request.getPayType() : "");
        return parkUpdateCarLog;
    }


    /**
     * 查询车辆具体更新记录
     *
     * @param updateLogRequest
     * @return
     */
    @Override
    public AjaxResult selectUpdateCarLog(UpdateLogRequest updateLogRequest) {
        Page<ParkUpdateCarLog> parkUpdateCarLogPage = queryParkUpdateCarlogList(updateLogRequest);
        if (parkUpdateCarLogPage != null) {
            List<ParkUpdateCarLog> records = parkUpdateCarLogPage.getRecords();
            records.forEach(parkUpdateCarLog -> {
                if (!UpdateTypeConstant.Park_ADD_BLACK.equals(parkUpdateCarLog.getStatus())) {
                    statisticSpaceList(parkUpdateCarLog);
                    statisticMngType(parkUpdateCarLog);
                } else {
                    statisticBlackInfo(parkUpdateCarLog);
                }
                statisticOperInfo(parkUpdateCarLog);
            });
            HashMap<String, Object> map = new HashMap<>(3);
            map.put("list", records);
            map.put("page", parkUpdateCarLogPage.getPages());
            map.put("count", parkUpdateCarLogPage.getTotal());
            return AjaxResult.success(map);
        }
        return AjaxResult.success();
    }

    private Page<ParkUpdateCarLog> queryParkUpdateCarlogList(UpdateLogRequest updateLogRequest) {
        String updateType = updateLogRequest.getUpdateType();
        LambdaQueryWrapper<ParkUpdateCarLog> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SecurityUtils.getParkId() != null, ParkUpdateCarLog::getParkId, SecurityUtils.getParkId());
        queryWrapper.eq(updateLogRequest.getCarId() != null, ParkUpdateCarLog::getCarId, updateLogRequest.getCarId());
        queryWrapper.eq(updateLogRequest.getId() != null, ParkUpdateCarLog::getId, updateLogRequest.getId());
        queryWrapper.eq(updateLogRequest.getFlag() != null, ParkUpdateCarLog::getFlag, updateLogRequest.getFlag());
        queryWrapper.like(StringUtils.isNotBlank(updateLogRequest.getPlates()), ParkUpdateCarLog::getPlates, updateLogRequest.getPlates());
        queryWrapper.gt(updateLogRequest.getBeginTime() != null, ParkUpdateCarLog::getUpdateTime, updateLogRequest.getBeginTime());
        queryWrapper.le(updateLogRequest.getEndTime() != null, ParkUpdateCarLog::getUpdateTime, updateLogRequest.getEndTime());
        if (UpdateTypeConstant.PARK_UPDATE_DELETE.equals(updateType) || UpdateTypeConstant.PARK_UPDATE_ADD.equals(updateType)) {
            queryWrapper.eq(ParkUpdateCarLog::getUpdateType, updateType);
        } else {
            queryWrapper.like(ParkUpdateCarLog::getUpdateType, updateType);
        }
        queryWrapper.like(StringUtils.isNotBlank(updateLogRequest.getOperName()), ParkUpdateCarLog::getOperName, updateLogRequest.getOperName());
        return parkUpdateCarLogMapper.selectPage(new Page<>(updateLogRequest.getPageNum(), updateLogRequest.getPageSize()), queryWrapper);
    }

    /**
     * 黑名单显示处理
     *
     * @param parkUpdateCarLog
     */
    private void statisticBlackInfo(ParkUpdateCarLog parkUpdateCarLog) {
        String mngType = parkUpdateCarLog.getMngType();
        if (StringUtils.isNotBlank(mngType)) {
            ParkCarMngtype parkCarMngtype = parkCarMngtypeMapper.selectById(Convert.toInt(mngType));
            parkUpdateCarLog.setBeforeMngType(parkCarMngtype.getName());
        } else {
            parkUpdateCarLog.setBeforeMngType("临停车");
        }
        parkUpdateCarLog.setMngType(UpdateTypeConstant.PARK_BLACK_NAME);
    }

    private void statisticOperInfo(ParkUpdateCarLog parkUpdateCarLog) {
        OperateDTO operateDTO = systemUserService.getOperate(parkUpdateCarLog.getOperId()).getData();
        Optional.ofNullable(operateDTO).ifPresent(a -> parkUpdateCarLog.setOperName(operateDTO.getOperateName()));
    }

    private void statisticMngType(ParkUpdateCarLog parkUpdateCarLog) {
        if (StringUtils.isNotBlank(parkUpdateCarLog.getBeforeMngType())){
            ParkCarMngtype parkCarMngtype = parkCarMngtypeMapper.selectById(parkUpdateCarLog.getBeforeMngType());
            parkUpdateCarLog.setBeforeMngType(parkCarMngtype.getName());
        }
        if (StringUtils.isNotBlank(parkUpdateCarLog.getMngType())) {
            ParkCarMngtype parkCarMngtype = parkCarMngtypeMapper.selectById(parkUpdateCarLog.getMngType());
            parkUpdateCarLog.setMngType(parkCarMngtype.getName());
        }
    }

    private void statisticSpaceList(ParkUpdateCarLog parkUpdateCarLog) {
        if (parkUpdateCarLog.getSpaceList() != null) {
            List<ParkCarAddGarageSpaceVo> parkCarAddGarageSpaces = JSONObject.parseArray(parkUpdateCarLog.getSpaceList(), ParkCarAddGarageSpaceVo.class);
            for (ParkCarAddGarageSpaceVo parkCarAddGarageSpaceVo : parkCarAddGarageSpaces) {
                ParkGarage parkGarage = parkGarageService.selectParkGarageById(parkCarAddGarageSpaceVo.getGarageId());
                parkCarAddGarageSpaceVo.setGarageName(parkGarage.getName());
            }
            parkUpdateCarLog.setSpaceLists(parkCarAddGarageSpaces);
        }

    }

    @Override
    public void generateAddBlackParkLog(BlackCarRequest request) {
        ParkUpdateCarLog parkUpdateCarLog = new ParkUpdateCarLog();
        parkUpdateCarLog.setBeginDate(DateUtils.parseDate(request.getBeginTime()));
        parkUpdateCarLog.setEndDate(DateUtils.parseDate(request.getEndTime()));
        parkUpdateCarLog.setUpdateTime(new Date());
        parkUpdateCarLog.setParkId(SecurityUtils.getParkId());
        parkUpdateCarLog.setOperId(SecurityUtils.getUserId());
        parkUpdateCarLog.setPlates(request.getPlate());
        parkUpdateCarLog.setRemark(request.getRemark());
        ParkCar parkCar = iParkCarService.selectParkCarById(request.getId());
        if (parkCar != null) {
            parkUpdateCarLog.setMngType(String.valueOf(parkCar.getMngTypeId()));
        }
        parkUpdateCarLog.setStatus(UpdateTypeConstant.Park_ADD_BLACK); //黑名单停用
        parkUpdateCarLog.setUpdateType(UpdateTypeConstant.PARK_UPDATE_MNGTYPE);
        parkUpdateCarLogMapper.insert(parkUpdateCarLog);
    }

    @Override
    public void generateAddVisitParkLog(ParkVisitorCarAddRequest request) {
        ParkUpdateCarLog parkUpdateCarLog = new ParkUpdateCarLog();
        parkUpdateCarLog.setUpdateTime(new Date());
        parkUpdateCarLog.setBeginDate(new Date());
        parkUpdateCarLog.setEndDate(request.getEndDate());
        parkUpdateCarLog.setParkId(SecurityUtils.getParkId());
        parkUpdateCarLog.setOperId(SecurityUtils.getUserId());
        parkUpdateCarLog.setPlates(request.getPlates());
        parkUpdateCarLog.setMngType(String.valueOf(request.getMngTypeId()));
        parkUpdateCarLog.setUserName(request.getName());
        parkUpdateCarLog.setPhone(request.getPhone());
        parkUpdateCarLog.setRemark(request.getRemark());
        parkUpdateCarLog.setUpdateType(UpdateTypeConstant.PARK_UPDATE_ADD);
        parkUpdateCarLog.setStatus(UpdateTypeConstant.Park_ADD_VISIT);  //访客车列表
        parkUpdateCarLogMapper.insert(parkUpdateCarLog);
    }


    @Override
    public AjaxResult queryParkUpdateDetailInfo(int id) {
        ParkUpdateCarLog parkUpdateCarLog = parkUpdateCarLogMapper.selectById(id);
        String mngType = parkUpdateCarLog.getMngType();
        String beforeMngType = parkUpdateCarLog.getBeforeMngType();
        if (StringUtils.isNotBlank(beforeMngType)){
            ParkCarMngtype parkCarMngtype = parkCarMngtypeMapper.selectById(Convert.toInt(beforeMngType));
            parkUpdateCarLog.setBeforeMngType(parkCarMngtype.getName());
        }else {
            parkUpdateCarLog.setBeforeMngType("普通临停类");
        }
        convertMngType(mngType,parkUpdateCarLog);
        if (StringUtils.isNotBlank(parkUpdateCarLog.getSpaceList())){
            List<ParkCarAddGarageSpaceVo> parkCarAddGarageSpaceVos = JSONObject.parseArray(parkUpdateCarLog.getSpaceList(), ParkCarAddGarageSpaceVo.class);
            parkCarAddGarageSpaceVos.forEach(c->{
                ParkGarage parkGarage = iParkGarageService.selectParkGarageById(c.getGarageId());
                c.setGarageName(parkGarage.getName());
            });
            parkUpdateCarLog.setSpaceLists(parkCarAddGarageSpaceVos);
        }
        return AjaxResult.success(parkUpdateCarLog);
    }

    /**
     * 处理当前管理类型
     * @param mngType
     * @param parkUpdateCarLog
     */
    private void convertMngType(String mngType, ParkUpdateCarLog parkUpdateCarLog) {
        if (StringUtils.isNotBlank(mngType)){
            if (UpdateTypeConstant.Park_ADD_VISIT.equals(parkUpdateCarLog.getStatus())){
                parkUpdateCarLog.setMngType(UpdateTypeConstant.PARK_VISIT_NAME);
            }else if (UpdateTypeConstant.Park_ADD_BLACK.equals(parkUpdateCarLog.getStatus())){
                parkUpdateCarLog.setMngType(UpdateTypeConstant.Park_ADD_BLACK);
            }else {
                ParkCarMngtype parkCarMngtype = parkCarMngtypeMapper.selectById(Convert.toInt(mngType));
                parkUpdateCarLog.setMngType(parkCarMngtype.getName());
            }
        }
    }
}




